#include "../../include/graphics/Renderable.hpp"
using namespace klas;
using namespace graphics;

Renderable::Renderable(Renderable *thisPtr)
{
  m_renderingLayer = 0;
  m_transparency = 1.0;
  /* TODO: register with scene */
}

Renderable::~Renderable()
{
  /* TODO: remove from the scene. */
}

void Renderable::setRot(double degrees)
{
  m_transform.rot = degrees;
}

void Renderable::setSize(const math::Vector2d &size)
{
  m_transform.size = size;
}

void Renderable::setSize(double sizeX, double sizeY)
{
  setSizeX(sizeX);
  setSizeY(sizeY);
}

void Renderable::setSize(double size)
{
  setSizeX(size);
  setSizeY(size);
}

void Renderable::setSizeX(double val)
{
  m_transform.size.x = val;
}

void Renderable::setSizeY(double val)
{
  m_transform.size.y = val;
}

void Renderable::setPos(const math::Vector2d &pos)
{
  m_transform.pos = pos;
}

void Renderable::setPos(double x, double y)
{
  m_transform.pos.x = x;
  m_transform.pos.y = y;
}

void Renderable::setTransformation(const Transformation& transform)
{
  m_transform = transform;
}

void Renderable::setRenderingLayer(uint16 layer)
{
  m_renderingLayer = layer;
}

double Renderable::getRot() const
{
  return m_transform.rot;
}

math::Vector2d& Renderable::getSize()
{
  return m_transform.size;
}

double Renderable::getSizeX() const
{
  return m_transform.size.x;
}

double Renderable::getSizeY() const
{
  return m_transform.size.y;
}

math::Vector2d& Renderable::getPos()
{
  return m_transform.pos;
}

double Renderable::getX() const
{
  return m_transform.pos.x;
}

double Renderable::getY() const
{
  return m_transform.pos.y;
}

Transformation Renderable::getTransformation() const
{
  return m_transform;
}

uint16 Renderable::getRenderingLayer() const
{
  return m_renderingLayer;
}

void Renderable::addChild(Renderable *child)
{
  m_children.push_back(child);
}

vector<Renderable*>& Renderable::getChildren()
{
  return m_children;
}

void Renderable::translate(double x, double y)
{
  m_transform.pos.x += x;
  m_transform.pos.y += y;
}

void Renderable::translate(const math::Vector2d &offset)
{
  m_transform.pos += offset;
}

double Renderable::getTransparency() const
{
  return m_transparency;
}

void Renderable::setTransparency(double transparency)
{
  // If we are below zero, then just set to zero.
  if(transparency < 0.0)
    transparency = 0;

  // Make sure the transparency is from zero to one (but allow a little bit of overshoot and just readjust to 1)
  if(transparency > 1.0 && transparency < 1.2)
    transparency = 1.0;

  transparency > 1.2 ? transparency /= 255.0 : false;

  // Set the transparency
  m_transparency = transparency;
}

void Renderable::render(RenderingCore* core)
{
  for(vector<Renderable*>::iterator it = m_children.begin(); it != m_children.end(); ++it)
  {
    if((*it)->m_children.size() != 0)
      (*it)->render(core);
    else
    {
      double transparency = (*it)->getTransparency();
      (*it)->setTransparency(m_transparency * (*it)->getTransparency());
      (*it)->renderElement(core, m_transform.pos);
      (*it)->setTransparency(transparency);
    }
  }
  renderElement(core, math::Vector2d(0, 0));
}